package com.jcj.endecoder;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

/**
 * 自定义长度解码器LengthFieldBasedFrameDecoder对发送接收数据的处理
 */
@ChannelHandler.Sharable
public class HandlerClientLengthFieldBased extends SimpleChannelInboundHandler<Object> {


    /**
     * 处理接收到的消息
     *
     * @param channelHandlerContext 通道的上下文
     * @param info                  接收字节序
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object info) throws Exception {

        ByteBuf in = (ByteBuf) info;
        //打印报文
        String srcInfo = ByteBufUtil.hexDump(in).toUpperCase();
        System.out.println("收到的原始报文: " + srcInfo);

        //报文解析
        short header = in.readShort();
        int msgtype = in.readByte();//这里读出来的byte直接自动转为int
        int contentLen = in.readInt();
        //根据内容所占的字节数读取出内容
        ByteBuf bufContent = in.readBytes(contentLen);
        String content = bufContent.toString(CharsetUtil.UTF_8);
        System.out.println("收到的消息为:" + content);
    }

    /**
     * 处理I/O事件的异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();//关闭当前Channel的连接
    }

    /**
     * 建立连接后该channelActive()方法只会被调用一次,这里的逻辑:建立连接后,字节序列被发送到服务器,编码格式是utf-8
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        //发送自定义协议格式的消息
        //包头,short:2个字节
        short header = 0x5A5A;
        //消息类型,1个字节
        byte[] msgtype = new byte[]{0x01};  //因为Unpooled.copiedBuffer()传入的参数需要byte[],所以一个字节我们也定义为byte[]
        //数据内容
        String strContent = "你好,天王盖地虎!";
        //数据的长度,int:4个字节
        int contentLen = strContent.getBytes().length;//获取字节的长度(不是字符串的长度)

        //写入通道
        ctx.write(Unpooled.copyShort(header));
        ctx.write(Unpooled.copiedBuffer(msgtype));
        ctx.write(Unpooled.copyInt(contentLen));
        ctx.write(Unpooled.copiedBuffer(strContent, CharsetUtil.UTF_8));
        //清空缓冲区,发送消息
        ctx.flush();
    }
}






























































